home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume22 / gnuchess / patch03 next >
Encoding:
Text File  |  1991-08-12  |  16.6 KB  |  618 lines

  1. Newsgroups: comp.sources.misc
  2. From: Mike McGann <mwm@hasler.ascom.ch>
  3. Subject:  v22i002:  gnuchess - gnuchess version 3.1+, Patch03
  4. Message-ID: <1991Aug13.043250.24690@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: c8b4fabf55f6def1ab97624c30b20e62
  6. Date: Tue, 13 Aug 1991 04:32:50 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Mike McGann <mwm@hasler.ascom.ch>
  10. Posting-number: Volume 22, Issue 2
  11. Archive-name: gnuchess/patch03
  12. Environment: UNIX, DOS
  13. Patch-To: gnuchess: Volume 19, Issue 73-79
  14.  
  15. Enclosed is patch3 for gnuchess3.1+. It is mainly improvements to handling
  16. the opening book. These came from Philippe Schnoebelen  phs@lifia.imag.fr.
  17. I have checked them out and they seem to function fine. The diffs are against
  18. gnuchess3.1+ patchlevel 2.
  19.  
  20. mike
  21. ---
  22. #! /bin/sh
  23. # This is a shell archive, meaning:
  24. # 1. Remove everything above the #! /bin/sh line.
  25. # 2. Save the resulting text in a file.
  26. # 3. Execute the file with /bin/sh (not csh) to create the files:
  27. #    README.patch3
  28. #    patch3
  29. # This archive created: Mon Aug 12 13:06:48 1991
  30. export PATH; PATH=/bin:$PATH
  31. if test -f 'README.patch3'
  32. then
  33.     echo shar: will not over-write existing file "'README.patch3'"
  34. else
  35. cat << \SHAR_EOF > 'README.patch3'
  36. This is patch3 for gnuchess3.1+, It contains a set of improvements
  37. and fixes mainly in handling the opening book. They came from
  38.  phs@lifia.imag.fr (Philippe Schnoebelen). Phillipe sent me the 
  39. following note about the changes.
  40.  
  41. Mike McGann
  42. mwm@hslrswi.hasler.ascom.ch
  43.  
  44. ---
  45. I've made some more minor modifications because:
  46.  
  47. 1) if you edit the board and use more than 16 men, gnuchess is lost,
  48.  
  49. 2) if you quit the opening book and then backtrack, gnuchess has lost the
  50. book, 
  51.  
  52. 3) if you edit the board, gnuchess still use its book !
  53.  
  54. In addition, I allowed the '?' to be used in the opening book. A move
  55. tagged with '?' is not played by gnuchess. This allows teaching the program
  56. how to refute unsound traps, without letting it playing them.
  57.  
  58. Here is the patch. Do you know if anybody is coordinating the GnuChess
  59. development project ?
  60.  
  61. --Philippe
  62. SHAR_EOF
  63. fi # end of overwriting check
  64. if test -f 'patch3'
  65. then
  66.     echo shar: will not over-write existing file "'patch3'"
  67. else
  68. cat << \SHAR_EOF > 'patch3'
  69. *** 1.1    1991/08/12 10:41:10
  70. --- ChangeLog    1991/08/12 10:50:22
  71. ***************
  72. *** 1,4 ****
  73. --- 1,31 ----
  74. + Tue Aug  6 18:10:47 1991  Philippe Schnoebelen  (phs@lifia.imag.fr)
  75. +     * Modify handling of Book in Undo (previously, when you
  76. +     backtracked after quitting the book, the program was not able to
  77. +     use it again)
  78. +     * Modify handling of Book in EditBoard and other routines so that
  79. +     the Book is not used if you don't start from the regular initial board.
  80. + Mon Aug  5 17:26:59 1991  Philippe Schnoebelen  (phs@lifia.imag.fr)
  81. +     * Modify parse in gnuchess.c so that a move can be followed by '?'
  82. +     indicating that the program should not play it itself. Such a move
  83. +     is stored with the highest bit raised.
  84. +           Modify OpeningBook in gnuchess.c so that moves with highest bit
  85. +     set are recognized but not played by the program.
  86. +     * Modify the declaration of array PieceList in gnuchess.[ch] to
  87. +     allow for up to 64 men of the same side. Such artificial
  88. +     situations can be built with edit and the program must be able to
  89. +     deal with them.
  90. + Mon Aug 1 10:20 1991 Mike McGann {mwm@hslrswi.hasler.ascom.ch)
  91. +     Split chesstool and xboard versions. Xboard is now
  92. +     gnuchessx and chesstool is gnuchessc.
  93.   Mon Apr 15 10:20 1991 Mike McGann {mwm@hslrswi.hasler.ascom.ch)
  94. +     Changed transposition table to cache positions found in transposition file
  95.       Fix Undo's incorrect handling of promotions.
  96.       Fix win and draw determination bugs.
  97.        Fix bug in algbr that prevented correct display of promotion moves.
  98. *** 1.2    1991/08/12 10:43:46
  99. --- Makefile    1991/08/12 10:50:22
  100. ***************
  101. *** 75,83 ****
  102.   postprint: postprint.o
  103.       $(CC) $(CFLAGS) -o postprint postprint.o
  104.       
  105. ! gnuchessd: gnuchess.c nuxdsp.c
  106. !     $(CC) $(CFLAGS) $(HASH) $(BOOK) -DCHESSTOOL -DDEBUG -o  gnuchessd  nondsp.c gnuchess.c
  107. !     rm nondsp.o gnuchess.o
  108.   
  109.   gnuan.o: gnuan.c gnuchess.h version.h
  110.       $(CC) $(CFLAGS) $(HASH) $(BOOK) -c gnuan.c
  111. --- 75,83 ----
  112.   postprint: postprint.o
  113.       $(CC) $(CFLAGS) -o postprint postprint.o
  114.       
  115. ! gnuchessd:  nondsp.c gnuchess.c
  116. !     $(CC) -Wall -fstrength-reduce -p -g -Dinline="" $(HASH) $(BOOK) -DCHESSTOOL -DDEBUG -o  gnuchessd  nondsp.c gnuchess.c
  117.   
  118.   gnuan.o: gnuan.c gnuchess.h version.h
  119.       $(CC) $(CFLAGS) $(HASH) $(BOOK) -c gnuan.c
  120. *** 1.1    1991/08/12 10:41:10
  121. --- gnuan.c    1991/08/12 10:50:23
  122. ***************
  123. *** 516,521 ****
  124. --- 516,523 ----
  125.     flag.mate = false;
  126.     Sdepth = 0;
  127.     InitializeStats ();
  128. +   if (flag.regularstart)
  129. +     Book = BKBook;
  130.   }
  131.   
  132.   void
  133. *** 1.1    1991/08/12 10:41:10
  134. --- gnuchess.book    1991/08/12 10:50:23
  135. ***************
  136. *** 3901,3903 ****
  137. --- 3901,3951 ----
  138.   d1e2  f6e4
  139.   a1c1  a8c8
  140.   !
  141. + ! Sicilian - Morra Gambit (declined)
  142. + e2e4  c7c5
  143. + d2d4? c5d4
  144. + c2c3  d4d3
  145. + !
  146. + e2e4  c7c5
  147. + d2d4? c5d4
  148. + g1f3  e7e6
  149. + !
  150. + ! Alekhine's Defence
  151. + e2e4  g8f6
  152. + f1c4  f6e4?
  153. + c4f7  e8f7
  154. + d1h5  f7e6
  155. + h5g4  e6d5
  156. + c2c4
  157. + !
  158. + e2e4  g8f6
  159. + f1c4  e7e5
  160. + !
  161. + ! Damiano defence (how to refute it)
  162. + e2e4 e7e5
  163. + g1f3 f7f6?
  164. + f3e5 f6e5
  165. + d1h5 e8e7
  166. + h5e5 e7f7
  167. + f1c4
  168. + !
  169. + ! Two Knights Defence
  170. + e2e4  e7e5
  171. + g1f3  b8c6
  172. + f1c4  g8f6
  173. + f3g5  d7d5
  174. + e4d5  f6d5?
  175. + g5f7  e8f7
  176. + d1f3  f7e6
  177. + b1c3
  178. + !
  179. + ! Hungarian Defence
  180. + e2e4  e7e5
  181. + g1f3  b8c6
  182. + f1c4  f8e7?
  183. + d2d4  e5d4
  184. + c2c3  d4c3
  185. + d1d5  g8h6
  186. + c1h6  e8g8
  187. + h6g7
  188. + !
  189. *** 1.1    1991/08/12 10:41:10
  190. --- gnuchess.c    1991/08/12 10:50:24
  191. ***************
  192. *** 145,151 ****
  193.   char listfile[128] = "";
  194.   struct leaf Tree[2000], *root;
  195.   short TrPnt[maxdepth];
  196. ! short PieceList[2][16], PawnCnt[2][8];
  197.   #define wking PieceList[white][0]
  198.   #define bking PieceList[black][0]
  199.   #define EnemyKing PieceList[c2][0]
  200. --- 145,151 ----
  201.   char listfile[128] = "";
  202.   struct leaf Tree[2000], *root;
  203.   short TrPnt[maxdepth];
  204. ! short PieceList[2][64], PawnCnt[2][8];
  205.   #define wking PieceList[white][0]
  206.   #define bking PieceList[black][0]
  207.   #define EnemyKing PieceList[c2][0]
  208. ***************
  209. *** 320,330 ****
  210.   const short Stcolor[64] =
  211.   {white, white, white, white, white, white, white, white,
  212.    white, white, white, white, white, white, white, white,
  213. !  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  214. !  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  215.    black, black, black, black, black, black, black, black,
  216.    black, black, black, black, black, black, black, black};
  217.   short board[64], color[64];
  218.   static unsigned char nextpos[8][64][64];
  219.   static unsigned char nextdir[8][64][64];
  220.   /*
  221. --- 320,346 ----
  222.   const short Stcolor[64] =
  223.   {white, white, white, white, white, white, white, white,
  224.    white, white, white, white, white, white, white, white,
  225. !  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  226. !  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  227. !  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  228. !  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
  229.    black, black, black, black, black, black, black, black,
  230.    black, black, black, black, black, black, black, black};
  231.   short board[64], color[64];
  232. + /* nextpos[piece][from-square] , nextdir[piece][from-square] gives vector of positions reachable from from-square 
  233. +     in ppos with piece such that the sequence    
  234. +             ppos = nextpos[piece][from-square];
  235. +             pdir = nextdir[piece][from-square];
  236. +             u = ppos[sq];
  237. +             do {
  238. +                 u = ppos[u];
  239. +                 if(color[u] != neutral) u = pdir[u];
  240. +             } while (sq != u);
  241. +     will generate the sequence of all squares reachable from sq.
  242. +     If the path is blocked u = pdir[sq] will generate the continuation of the sequence in other directions.
  243. + */
  244. +     
  245.   static unsigned char nextpos[8][64][64];
  246.   static unsigned char nextdir[8][64][64];
  247.   /*
  248. ***************
  249. *** 337,342 ****
  250. --- 353,359 ----
  251.   {
  252.     no_piece, pawn, knight, bishop, rook, queen, king, no_piece,
  253.     no_piece, bpawn, knight, bishop, rook, queen, king, no_piece};
  254. + /* data used to generate nextpos/nextdir */
  255.   static const short direc[8][8] =
  256.   {
  257.     0, 0, 0, 0, 0, 0, 0, 0,
  258. ***************
  259. *** 691,696 ****
  260. --- 708,714 ----
  261.     time0 = time ((long *) 0);
  262.     ElapsedTime (1);
  263.     UpdateDisplay (0, 0, 1, 0);
  264. +   flag.regularstart = true;
  265.     Book = BKBook;
  266.   }
  267.   
  268. ***************
  269. *** 800,806 ****
  270.   
  271.         for (i = TrPnt[1]; i < TrPnt[2]; i++)
  272.       pick (i, TrPnt[2] - 1);
  273. !       if (Book != NULL)
  274.       OpeningBook (&hint);
  275.         if (Book != NULL)
  276.       flag.timeout = true;
  277. --- 818,824 ----
  278.   
  279.         for (i = TrPnt[1]; i < TrPnt[2]; i++)
  280.       pick (i, TrPnt[2] - 1);
  281. !       if (flag.regularstart && Book != NULL)
  282.       OpeningBook (&hint);
  283.         if (Book != NULL)
  284.       flag.timeout = true;
  285. ***************
  286. *** 862,868 ****
  287.     if (rpt >= 2)
  288.       {
  289.         root->flags |= draw;
  290. !       DRAW = "Repitition";
  291.       }
  292.     if (score < -12000)
  293.       {
  294. --- 880,886 ----
  295.     if (rpt >= 2)
  296.       {
  297.         root->flags |= draw;
  298. !       DRAW = "Repetition";
  299.       }
  300.     if (score < -12000)
  301.       {
  302. ***************
  303. *** 931,937 ****
  304.     while ((c = getc (fd)) == ' ') ;
  305.     i = 0;
  306.     s[0] = (char) c;
  307. !   while (c != ' ' && c != '\n' && c != EOF)
  308.       s[++i] = (char) (c = getc (fd));
  309.     s[++i] = '\0';
  310.     if (c == EOF)
  311. --- 949,955 ----
  312.     while ((c = getc (fd)) == ' ') ;
  313.     i = 0;
  314.     s[0] = (char) c;
  315. !   while (c != '?' && c != ' ' && c != '\t' && c != '\n' && c != EOF)
  316.       s[++i] = (char) (c = getc (fd));
  317.     s[++i] = '\0';
  318.     if (c == EOF)
  319. ***************
  320. *** 954,959 ****
  321. --- 972,981 ----
  322.         r2 = s[3] - '1';
  323.         *mv = (locn (r1, c1) << 8) | locn (r2, c2);
  324.       }
  325. +   if (c == '?') {        /* Bad move, not for the program to play */
  326. +     *mv |= 0x8000;        /* Flag it ! */
  327. +     c = getc(fd);
  328. +  }
  329.     return (1);
  330.   }
  331.   
  332. ***************
  333. *** 965,971 ****
  334.      into an unsigned integer format indicating the from and to square. Create
  335.      a linked list of opening lines of play, with entry->next pointing to the
  336.      next line and entry->move pointing to a chunk of memory containing the
  337. !    moves. More Opening lines of up to 256 half moves may be added to
  338.      gnuchess.book.
  339.   */
  340.   #ifndef BOOK
  341. --- 987,993 ----
  342.      into an unsigned integer format indicating the from and to square. Create
  343.      a linked list of opening lines of play, with entry->next pointing to the
  344.      next line and entry->move pointing to a chunk of memory containing the
  345. !    moves. More Opening lines of up to 100 half moves may be added to
  346.      gnuchess.book.
  347.   */
  348.   #ifndef BOOK
  349. ***************
  350. *** 1036,1042 ****
  351.     unsigned short m, *mp;
  352.     unsigned r, r0;
  353.     struct BookEntry *p;
  354.     srand ((unsigned int) time ((long *) 0));
  355.     r0 = m = 0;
  356.     p = Book;
  357. --- 1058,1064 ----
  358.     unsigned short m, *mp;
  359.     unsigned r, r0;
  360.     struct BookEntry *p;
  361. !   
  362.     srand ((unsigned int) time ((long *) 0));
  363.     r0 = m = 0;
  364.     p = Book;
  365. ***************
  366. *** 1044,1057 ****
  367.       {
  368.         mp = p->mv;
  369.         for (j = 1; j <= GameCnt; j++)
  370. !     if (GameList[j].gmove != *(mp++))
  371.         break;
  372. !       if (j > GameCnt)
  373.       if ((r = urand ()) > r0)
  374.         {
  375.           r0 = r;
  376. !         m = *mp;
  377. !         *hint = *(++mp);
  378.         }
  379.         p = p->next;
  380.       }
  381. --- 1066,1080 ----
  382.       {
  383.         mp = p->mv;
  384.         for (j = 1; j <= GameCnt; j++)
  385. !     if ( GameList[j].gmove != (*(mp++) & 0x7FFF) ) {
  386.         break;
  387. !        }
  388. !       if ( (j > GameCnt) && ((*mp & 0x8000) == 0) )
  389.       if ((r = urand ()) > r0)
  390.         {
  391.           r0 = r;
  392. !         m = (*mp & 0x7FFF);
  393. !         *hint = (*(++mp) & 0x7FFF);
  394.         }
  395.         p = p->next;
  396.       }
  397. *** 1.1    1991/08/12 10:41:10
  398. --- gnuchess.h    1991/08/12 10:50:24
  399. ***************
  400. *** 109,114 ****
  401. --- 109,115 ----
  402.     short mate;        /* the game is over */
  403.     short post;        /* show principle variation */
  404.     short quit;        /* quit/exit gnuchess */
  405. +   short regularstart;    /* did the game start from standard initial board ? */
  406.     short reverse;    /* reverse board display */
  407.     short bothsides;    /* computer plays both sides */
  408.     short hash;        /* enable/disable transposition table */
  409. ***************
  410. *** 123,129 ****
  411.   extern char savefile[128], listfile[128];
  412.   extern short TrPnt[maxdepth];
  413.   extern short board[64], color[64];
  414. ! extern short PieceList[2][16], PawnCnt[2][8];
  415.   extern short castld[2], Mvboard[64];
  416.   extern short svalue[64];
  417.   extern struct flags flag;
  418. --- 124,130 ----
  419.   extern char savefile[128], listfile[128];
  420.   extern short TrPnt[maxdepth];
  421.   extern short board[64], color[64];
  422. ! extern short PieceList[2][64], PawnCnt[2][8];
  423.   extern short castld[2], Mvboard[64];
  424.   extern short svalue[64];
  425.   extern struct flags flag;
  426. ***************
  427. *** 136,142 ****
  428.   extern struct GameRec GameList[200];
  429.   extern short GameCnt, Game50;
  430.   extern short Sdepth, MaxSearchDepth;
  431. ! extern struct BookEntry *Book;
  432.   extern struct TimeControlRec TimeControl;
  433.   extern short TCflag, TCmoves, TCminutes, OperatorTime;
  434.   extern const short otherside[3];
  435. --- 137,143 ----
  436.   extern struct GameRec GameList[200];
  437.   extern short GameCnt, Game50;
  438.   extern short Sdepth, MaxSearchDepth;
  439. ! extern struct BookEntry *Book, *BKBook;
  440.   extern struct TimeControlRec TimeControl;
  441.   extern short TCflag, TCmoves, TCminutes, OperatorTime;
  442.   extern const short otherside[3];
  443. *** 1.3    1991/08/12 10:43:46
  444. --- nondsp.c    1991/08/12 10:50:24
  445. ***************
  446. *** 148,153 ****
  447. --- 148,160 ----
  448.           {
  449.             mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  450.             mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  451. + #ifdef CHESSTOOL
  452. +           mvstr[3][0] = mvstr[0][0]; /* Allow e7e8 for chesstool */
  453. +           mvstr[3][1] = mvstr[0][1];
  454. +           mvstr[3][2] = mvstr[0][2];
  455. +           mvstr[3][3] = mvstr[0][3];
  456. +           mvstr[3][4] = '\0';
  457. + #endif
  458.           }
  459.         mvstr[2][m3p] = mvstr[1][2] = '\0';
  460.       }
  461. ***************
  462. *** 340,345 ****
  463. --- 347,354 ----
  464.     short a, r, c, sq, i;
  465.     char s[80];
  466.   
  467. +   flag.regularstart = false;
  468. +   Book = NULL;
  469.     ClrScreen ();
  470.     UpdateDisplay (0, 0, 1, 0);
  471.     printz (".   exit to main\n");
  472. ***************
  473. *** 802,807 ****
  474. --- 811,818 ----
  475.           }
  476.       }
  477.         GameCnt = 0;
  478. +       flag.regularstart = false;
  479. +       Book = NULL;
  480.         fgets (fname, 256, fd);
  481.         fgets (fname, 256, fd);
  482.         fgets (fname, 256, fd);
  483. ***************
  484. *** 863,868 ****
  485. --- 874,881 ----
  486.     if ((fd = fopen (fname, "r")) != NULL)
  487.       {
  488.         NewGame ();
  489. +       flag.regularstart = false;
  490. +       Book = NULL;
  491.         fgets (fname, 256, fd);
  492.         fname[6] = '\0';
  493.         if (strcmp (fname, "xboard"))
  494. ***************
  495. *** 1057,1062 ****
  496. --- 1070,1077 ----
  497.     ShowSidetoMove();
  498.     UpdateDisplay (0, 0, 1, 0);
  499.     InitializeStats ();
  500. +   if (flag.regularstart)
  501. +     Book = BKBook;
  502.   }
  503.   
  504.   void
  505. *** 1.1    1991/08/12 10:41:10
  506. --- nuxdsp.c    1991/08/12 10:50:24
  507. ***************
  508. *** 381,386 ****
  509. --- 381,388 ----
  510.     short a, r, c, sq, i;
  511.     char s[80];
  512.   
  513. +   flag.regularstart = false;
  514. +   Book = NULL;
  515.     ClrScreen ();
  516.     UpdateDisplay (0, 0, 1, 0);
  517.     gotoXY (TAB, 3);
  518. ***************
  519. *** 1137,1142 ****
  520. --- 1139,1146 ----
  521.       }
  522.       }
  523.     GameCnt = 0;
  524. +   flag.regularstart = false;
  525. +   Book = NULL;
  526.     fgets (fname, 256, fd);
  527.     fgets (fname, 256, fd);
  528.     fgets (fname, 256, fd);
  529. ***************
  530. *** 1206,1211 ****
  531. --- 1210,1217 ----
  532.     if ((fd = fopen (fname, "r")) != NULL)
  533.       {
  534.         NewGame ();
  535. +       flag.regularstart = false;
  536. +       Book = NULL;
  537.         fgets (fname, 256, fd);
  538.         fname[6] = '\0';
  539.         if (strcmp (fname, "xboard"))
  540. ***************
  541. *** 1423,1428 ****
  542. --- 1429,1436 ----
  543.     ShowSidetoMove ();
  544.     UpdateDisplay (0, 0, 1, 0);
  545.     InitializeStats ();
  546. +   if (flag.regularstart)
  547. +     Book = BKBook;
  548.   }
  549.   
  550.   void
  551. *** 1.1    1991/08/12 10:41:10
  552. --- uxdsp.c    1991/08/12 10:50:24
  553. ***************
  554. *** 344,349 ****
  555. --- 344,351 ----
  556.     short a, r, c, sq, i;
  557.     char s[80];
  558.   
  559. +   flag.regularstart = false;
  560. +   Book = NULL;
  561.     ClrScreen ();
  562.     UpdateDisplay (0, 0, 1, 0);
  563.     gotoXY (TAB, 3);
  564. ***************
  565. *** 978,983 ****
  566. --- 980,987 ----
  567.       }
  568.       }
  569.     GameCnt = 0;
  570. +   flag.regularstart = false;
  571. +   Book = NULL;
  572.     fgets (fname, 256, fd);
  573.     fgets (fname, 256, fd);
  574.     fgets (fname, 256, fd);
  575. ***************
  576. *** 1049,1054 ****
  577. --- 1053,1060 ----
  578.     if ((fd = fopen (fname, "r")) != NULL)
  579.       {
  580.         NewGame ();
  581. +       flag.regularstart = false;
  582. +       Book = NULL;
  583.         fgets (fname, 256, fd);
  584.         fname[6] = '\0';
  585.         if (strcmp (fname, "xboard"))
  586. ***************
  587. *** 1266,1271 ****
  588. --- 1272,1279 ----
  589.     ShowSidetoMove();
  590.     UpdateDisplay (0, 0, 1, 0);
  591.     InitializeStats ();
  592. +   if (flag.regularstart)
  593. +     Book = BKBook;
  594.   }
  595.   
  596.   void
  597. SHAR_EOF
  598. fi # end of overwriting check
  599. #    End of shell archive
  600. exit 0
  601.  
  602. exit 0 # Just in case...
  603. -- 
  604. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  605. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  606. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  607. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  608.